package top.aigoo.project01.utils;

import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import top.aigoo.project01.entity.dto.ImageHolder;

import javax.imageio.ImageIO;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * @Description: 图片处理工具类，使用Thumbnailator
 * https://mvnrepository.com/artifact/net.coobird/thumbnailator/0.4.8
 * @Author: Mr.OYSHUO.欧阳大叔  mail:1642302522@qq.com
 * @Version 1.0.0
 * @Date: 2021/8/8 17:34
 */
public class ImageUtil {
    private static Logger logger = LoggerFactory.getLogger(ImageUtil.class);
    /*获取到classpath的绝对值路径*/
    private static String basePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
    /*日期格式化工具*/
    private static final SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
    /*随机数*/
    private static final Random r = new Random();

    /**
     * storepath 是文件的路径还是目录的路径
     * 如果storePath 是 文件路径则删除该文件
     * 如果storePath是目录路径则删除该目录下的所有文件
     */
    public static void deleteFileOrPath(String storePath) {
        //获取文件全路径
        File fileOrPath = new File(PathUtil.getImgBasePath() + storePath);
        if (fileOrPath.exists()) {
            //是否是一个目录
            if (fileOrPath.isDirectory()) {
                File[] files = fileOrPath.listFiles();
                for (File file : files) {
                    file.delete();
                }
            }
            //删除目录
            fileOrPath.delete();
        }

    }

    /**
     * 处理缩略图,并返回新生成图片的相对路径值
     *
     * @param thumbnail  原始文件
     * @param targetAddr 存储的目的地址
     */
    public static String generateThumbnail(ImageHolder thumbnail, String targetAddr) {
        //生成文件名
        String realFileName = getRandomFileName();
        //获取文件扩展名
        String extension = getFileExtension(thumbnail.getImageName());
        //创建文件目录
        makeDirPath(targetAddr);

        String relativeAddr = targetAddr + realFileName + extension;

        logger.debug("current relativeAddr is:" + relativeAddr);
        // 生成文件
        File dest = new File(PathUtil.getImgBasePath() + relativeAddr);

        logger.debug("current complete addr is:" + PathUtil.getImgBasePath() + relativeAddr);
        try {
            Thumbnails.of(thumbnail.getImage()).size(200, 200)
                    .watermark(Positions.BOTTOM_RIGHT,
                            ImageIO.read(new File(basePath + "watermark.png")),
                            0.5f)
                    .outputQuality(0.8f)
                    .toFile(dest);
        } catch (IOException e) {
            logger.error(e.toString());
            e.printStackTrace();
        }
        return relativeAddr;
    }

    /**
     * 创建目标目标所涉及到的目录，既/home/work/xiangzai/xxx.jpg，那么 home, work,xiangzai这三个文件夹都自动创建
     *
     * @param targetURI 目标文件所述文件夹的相对路径
     */
    private static void makeDirPath(String targetURI) {
        String realFileParentPath = PathUtil.getImgBasePath() + targetURI;
        File dirPath = new File(realFileParentPath);
        if (!dirPath.exists()) {
            dirPath.mkdirs();
        }
    }

    /**
     * 获取输入文件流的扩展名
     *
     * @param cFile 输入文件流
     * @return
     */
    private static String getFileExtension(CommonsMultipartFile cFile) {
        /*1.获取文件流文件名*/
        String originalFileName = cFile.getOriginalFilename();
        /*2. 获取.后面的字符*/
        return originalFileName.substring(originalFileName.lastIndexOf("."));
    }

    private static String getFileExtension(String fileName) {

        return fileName.substring(fileName.lastIndexOf("."));
    }

    /**
     * 生成文件随机文件名字,当前年月日小时分钟秒+五位随机数
     *
     * @return 随机文件名
     */
    public static String getRandomFileName() {
        /*获取随机的五位数*/
        int randNum = r.nextInt(89999) + 10000;
        /*2. 当前时间*/
        String nowTimeStr = sDateFormat.format(new Date());
        /*3 返回随机文件名*/
        return nowTimeStr + randNum;
    }

    /*从inputStream接收文件存入到file*/
    public static void inputStreamToFile(InputStream ins, File file) {
        FileOutputStream os = null;
        try {
            os = new FileOutputStream(file);
            int byteRead = 0;
            byte[] buffer = new byte[1024];
            while ((byteRead = ins.read(buffer)) != -1) {
                os.write(buffer, 0, byteRead);
            }
        } catch (Exception e) {
            throw new RuntimeException("调用inputStreamToFile产生异常" + e.getMessage());
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (ins != null) {
                    ins.close();
                }
            } catch (IOException e) {
                throw new RuntimeException("inputStreamToFile关闭io产生异常" + e.getMessage());
            }

        }
    }

    public static void main(String[] args) {
        /**
         * of :传入需要处理的文件，可以传入文件，也可以传入图片流
         *  size: 输出图片的尺寸大小
         *  watermark： 参数1 水印位置 右下角，水印图片的路径, 第三个参数，压缩比
         *  outputQuality 输出文件的压缩比
         *  toFile：输出文件地址
         */

        System.out.println("ceshi" + basePath + "watermark.png");
        try {
            Thumbnails.of(new File("G:\\baidu\\wbrk\\images\\xiaohuangren.png"))
                    .size(200, 200)
                    .watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(basePath + "watermark.png")), 0.5f)
                    .outputQuality(0.8)
                    .toFile(new File("G:\\baidu\\wbrk\\images\\xiaohuangren-new.png"));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 处理详情图,并返回新生成图片的相对路径
     *
     * @param thumbnail
     * @param targetAddr
     * @return
     */
    public static String generateNormalImg(ImageHolder thumbnail, String targetAddr) {
        //生成不重复的随机文件名
        String realFileName = getRandomFileName();
        //获取文件扩展名如png,jpg等
        String extension = getFileExtension(thumbnail.getImageName());
        //如果目标路径不存在，则自动创建
        makeDirPath(targetAddr);
        //组合生成文件存储的相对路径(带文件名）
        String relativeAddr = targetAddr + realFileName + extension;
        logger.debug("current relativeAddr is:" + relativeAddr);
        // 生成文件要保存到的目标路径
        File dest = new File(PathUtil.getImgBasePath() + relativeAddr);

        logger.debug("current complete addr is:" + PathUtil.getImgBasePath() + relativeAddr);
        //调用Thumbnaill生成带有水印的图片
        try {
            Thumbnails.of(thumbnail.getImage()).size(337, 640)
                    .watermark(Positions.BOTTOM_RIGHT,
                            ImageIO.read(new File(basePath + "watermark.png")),
                            0.5f)
                    .outputQuality(0.9f)
                    .toFile(dest);
        } catch (IOException e) {
            logger.error(e.toString());
            throw new RuntimeException("创建缩略图片失败:" + e.toString());
        }
        //返回图片的相对路径地址
        return relativeAddr;
    }

    public static List<String> generateNormalImgs(List<CommonsMultipartFile> productImgs, String targetAddr) {
        List<String> imgAddrList = new ArrayList<String>();

        for (CommonsMultipartFile productImg : productImgs) {
            //生成不重复的随机文件名
            String realFileName = getRandomFileName();
            //获取文件扩展名如png,jpg等
            String extension = getFileExtension(productImg.getOriginalFilename());
            //如果目标路径不存在，则自动创建
            makeDirPath(targetAddr);
            //组合生成文件存储的相对路径(带文件名）
            String relativeAddr = targetAddr + realFileName + extension;
            logger.debug("current relativeAddr is:" + relativeAddr);
            // 生成文件要保存到的目标路径
            File dest = new File(PathUtil.getImgBasePath() + relativeAddr);

            logger.debug("current complete addr is:" + PathUtil.getImgBasePath() + relativeAddr);
            //调用Thumbnaill生成带有水印的图片
            try {
                Thumbnails.of(productImg.getInputStream()).size(337, 640)
                        .watermark(Positions.BOTTOM_RIGHT,
                                ImageIO.read(new File(basePath + "watermark.png")),
                                0.5f)
                        .outputQuality(0.9f)
                        .toFile(dest);
            } catch (IOException e) {
                logger.error(e.toString());
                throw new RuntimeException("创建缩略图片失败:" + e.toString());
            }
            //返回图片的相对路径地址
            imgAddrList.add(relativeAddr);
        }
        return imgAddrList;
    }

    public static String generateThumbnail(CommonsMultipartFile thumbnail, String targetAddr) {
        String realFileName = ImageUtil.getRandomFileName();
        String extension = getFileExtension(thumbnail);
        makeDirPath(targetAddr);
        String relativeAddr = targetAddr + realFileName + extension;
        File dest = new File(PathUtil.getImgBasePath() + relativeAddr);
        try {
            Thumbnails.of(thumbnail.getInputStream()).size(200, 200).outputQuality(0.25f).toFile(dest);
        } catch (IOException e) {
            throw new RuntimeException("创建缩略图失败：" + e.toString());
        }
        return relativeAddr;
    }
}
